package org.lee.mq;

import lombok.extern.slf4j.Slf4j;
import org.lee.mq.config.RabbitMqConstants;
import org.lee.mq.util.JsonUtil;
import org.lee.mq.util.StringUtil;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author jackielee
 * @version 1.0
 * @description NotifyMessageService
 * @date 2021/7/5
 **/
@Slf4j
@Component
public class NotifyMessageSender {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 确认消息回调监听接口，确认消息是否被broker收到
     */
    final ConfirmCallback confirmCallback = (correlationData, ack, cause) -> log.warn("消息ACK结果：{}, correlationData: {}", ack, correlationData.getId());
 
    /**
     * 发送
     *
     * @param routeKey     路由key
     * @param message      消息内容
     * @param properties   附加属性
     * @param exchangeName 交换机
     */
    public void send(String exchangeName, String routeKey, Object message, Map<String, Object> properties) {
        MessageHeaders mhs = new MessageHeaders(properties);
        Message<?> msg = MessageBuilder.createMessage(JsonUtil.toJson(message), mhs);
        rabbitTemplate.setConfirmCallback(confirmCallback);
        CorrelationData correlationData = new CorrelationData(StringUtil.Uuid());
        MessagePostProcessor mpp = message1 -> {
            log.warn("post to do:{}", message1);
            return message1;
        };
        rabbitTemplate.convertAndSend(RabbitMqConstants.ORDER_PAY_NOTIFY_EXCHANGE_NAME, routeKey, msg, mpp, correlationData);
    }

    /**
     * 发送订单回调
     *
     * @param message    消息内容
     * @param properties 附加属性
     * @param routeKey   路由
     */
    public void sendOrder(String routeKey, Object message, Map<String, Object> properties) {
        send(RabbitMqConstants.ORDER_PAY_NOTIFY_EXCHANGE_NAME, routeKey, message, properties);
    }

    /**
     * 发送订单回调
     *
     * @param message    消息内容
     * @param properties 附加属性
     * @param routeKey   路由
     */
    public void sendRefund(String routeKey, Object message, Map<String, Object> properties) {
        send(RabbitMqConstants.ORDER_REFUND_NOTIFY_EXCHANGE_NAME, routeKey, message, properties);
    }

    /**
     * 发送订单回调
     *
     * @param message    消息内容
     * @param properties 附加属性
     */
    public void sendOrderPayNotify(Object message, Map<String, Object> properties) {
        sendOrder(RabbitMqConstants.ORDER_PAY_NOTIFY_ROUTE_KEY, message, properties);
    }

    /**
     * 发送订单完成回调
     *
     * @param message    消息内容
     * @param properties 附加属性
     */
    public void sendOrderPayFinishNotify(Object message, Map<String, Object> properties) {
        sendOrder(RabbitMqConstants.ORDER_PAY_FINISH_NOTIFY_ROUTE_KEY, message, properties);
    }

    /**
     * 发送退款回调
     *
     * @param message    消息内容
     * @param properties 附加属性
     */
    public void sendRefundNotify(Object message, Map<String, Object> properties) {
        sendRefund(RabbitMqConstants.ORDER_REFUND_NOTIFY_ROUTE_KEY, message, properties);
    }

    /**
     * 发送退款完成回调
     *
     * @param message    消息内容
     * @param properties 附加属性
     */
    public void sendRefundFinishNotify(Object message, Map<String, Object> properties) {
        sendRefund(RabbitMqConstants.ORDER_REFUND_FINISH_NOTIFY_ROUTE_KEY, message, properties);
    }
}
